package com.ddw.meedeeuh.shared;

public class Sleep {

	private static final long NANOSECONDS_IN_MILLISECOND = 1000000;
	private long stamp;

	/**
	 * Utility function to run an action and time it. If the action
	 * takes longer than the specified period then the thread is slept
	 * for a length of time. This helps UI updates from being shown too quickly
	 * @param runner the action to run
	 * @param period the minimum time period for the action to run in milliseconds
	 * @param sleepFor the length of time to sleep if the action is quicker than the period (in milliseconds)
	 * @throws InterruptedException if there is a problem sleeping the thread
	 */
	public static void ifQuickerThan(Runnable runner, int period, int sleepFor) throws InterruptedException {
		final Sleep sleep = new Sleep();
		runner.run();
		sleep.ifQuickerThan(period, sleepFor);
	}

	/**
	 * Creates a new sleep instance, the start time is set to
	 * the systems nano time
	 */
	public Sleep() {
		reset();
	}

	/**
	 * Resets the start time stamp
	 */
	public void reset() {
		this.stamp = System.nanoTime();
	}

	/**
	 * Method to sleep the thread if the length of time between this
	 * objects construction and this method call is less than the period
	 * parameter.
	 * @param period the minimum time period in milliseconds
	 * @param sleepFor the length of time to sleep if it is quicker than the period (in milliseconds)
	 * @throws InterruptedException if there is a problem sleeping the thread
	 */
	public void ifQuickerThan(int period, int sleepFor) throws InterruptedException {
		long nanoseconds = (long)period * NANOSECONDS_IN_MILLISECOND;
		final long diff = System.nanoTime() - this.stamp;
		if(diff < nanoseconds) {
			Thread.sleep(sleepFor);
		}
	}

}
